using Microsoft.Phone.Controls.Maps.AutomationPeers;
using Microsoft.Phone.Controls.Maps.Core;
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Shapes;
namespace Microsoft.Phone.Controls.Maps.Overlays
{
	[TemplatePart(Name = "ScaleRectangle", Type = typeof(Rectangle)), TemplatePart(Name = "ScaleString", Type = typeof(ShadowText))]
	public class Scale : Overlay
	{
		internal const string ScaleStringElementName = "ScaleString";
		internal const string ScaleRectangleElementName = "ScaleRectangle";
		private const int metersPerKm = 1000;
		private const double yardsPerMeter = 1.0936133;
		private const int yardsPerMile = 1760;
		private const int feetPerYard = 3;
		private const double feetPerMeter = 3.2808398999999997;
		private const int feetPerMile = 5280;
		private double currentMetersPerPixel;
		private double previousMaxWidth;
		private RegionInfo regionInfo;
		private double scaleInMetersPerPixel;
		private Rectangle scaleRectangle;
		private ShadowText scaleString;
		private ModeBackground setForBackground;
		public static readonly DependencyProperty DistanceUnitProperty = DependencyProperty.Register("DistanceUnit", typeof(DistanceUnit), typeof(Scale), new PropertyMetadata(new PropertyChangedCallback(Scale.OnUnitChanged)));
		public static readonly DependencyProperty CultureProperty = DependencyProperty.Register("Culture", typeof(CultureInfo), typeof(Scale), new PropertyMetadata(new PropertyChangedCallback(Scale.OnCultureChanged)));
		private static readonly int[] singleDigitValues = new int[]
		{
			5,
			2
		};
		private static readonly double[] multiDigitValues = new double[]
		{
			5.0,
			2.5,
			2.0
		};
		public double MetersPerPixel
		{
			get
			{
				return this.scaleInMetersPerPixel;
			}
			internal set
			{
				this.scaleInMetersPerPixel = value;
				this.OnPerPixelChanged();
			}
		}
		public DistanceUnit DistanceUnit
		{
			get
			{
				return (DistanceUnit)base.GetValue(Scale.DistanceUnitProperty);
			}
			set
			{
				base.SetValue(Scale.DistanceUnitProperty, value);
			}
		}
		public CultureInfo Culture
		{
			get
			{
				return (CultureInfo)base.GetValue(Scale.CultureProperty);
			}
			set
			{
				base.SetValue(Scale.CultureProperty, value);
			}
		}
		internal ModeBackground SetForBackground
		{
			get
			{
				return this.setForBackground;
			}
			set
			{
				this.setForBackground = value;
				if (this.setForBackground == ModeBackground.Light)
				{
					this.scaleString.SetForegroundColorsForLightBackground();
					return;
				}
				this.scaleString.SetForegroundColorsForDarkBackground();
			}
		}
		public Scale()
		{
			base.set_DefaultStyleKey(typeof(Scale));
			base.set_MaxWidth(150.0);
			this.scaleString = new ShadowText();
			this.scaleRectangle = new Rectangle();
			base.add_LayoutUpdated(new EventHandler(this.Scale_LayoutUpdated));
		}
		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			this.scaleString = (base.GetTemplateChild("ScaleString") as ShadowText);
			this.scaleRectangle = (base.GetTemplateChild("ScaleRectangle") as Rectangle);
			this.Refresh();
			base.FireTemplateApplied();
		}
		private void SetScaling(double metersPerPixel)
		{
			if (base.get_Visibility() == null && metersPerPixel > 0.0)
			{
				CultureInfo cultureInfo = (this.Culture != null) ? this.Culture : CultureInfo.get_CurrentUICulture();
				DistanceUnit distanceUnit = this.DistanceUnit;
				if (distanceUnit == DistanceUnit.Default)
				{
					RegionInfo regionInfo = (this.regionInfo != null) ? this.regionInfo : RegionInfo.get_CurrentRegion();
					distanceUnit = (regionInfo.get_IsMetric() ? DistanceUnit.KilometersMeters : DistanceUnit.MilesFeet);
				}
				double maxWidth = base.get_MaxWidth();
				this.previousMaxWidth = maxWidth;
				if (DistanceUnit.KilometersMeters == distanceUnit)
				{
					double num = metersPerPixel * maxWidth;
					if (num > 1000.0)
					{
						double dIn = num / 1000.0;
						int num2 = Scale.LargestNiceNumber(dIn);
						int pixels = (int)((double)(num2 * 1000) / metersPerPixel);
						this.SetScaling(pixels, string.Format(cultureInfo, OverlayResources.Kilometers, new object[]
						{
							num2
						}));
					}
					else
					{
						int num3 = Scale.LargestNiceNumber(num);
						int pixels2 = (int)((double)num3 / metersPerPixel);
						this.SetScaling(pixels2, string.Format(cultureInfo, OverlayResources.Meters, new object[]
						{
							num3
						}));
					}
				}
				else
				{
					double num4 = metersPerPixel * 3.2808398999999997;
					double num5 = num4 * maxWidth;
					if (num5 > 5280.0)
					{
						double dIn2 = num5 / 5280.0;
						int num6 = Scale.LargestNiceNumber(dIn2);
						int pixels3 = (int)((double)(num6 * 5280) / num4);
						this.SetScaling(pixels3, string.Format(cultureInfo, OverlayResources.Miles, new object[]
						{
							num6
						}));
					}
					else
					{
						if (DistanceUnit.MilesFeet == distanceUnit)
						{
							int num7 = Scale.LargestNiceNumber(num5);
							int pixels4 = (int)((double)num7 / num4);
							this.SetScaling(pixels4, string.Format(cultureInfo, OverlayResources.Feet, new object[]
							{
								num7
							}));
						}
						else
						{
							double dIn3 = num5 / 3.0;
							int num8 = Scale.LargestNiceNumber(dIn3);
							int pixels5 = (int)((double)(num8 * 3) / num4);
							this.SetScaling(pixels5, string.Format(cultureInfo, OverlayResources.Yards, new object[]
							{
								num8
							}));
						}
					}
				}
				this.currentMetersPerPixel = metersPerPixel;
			}
		}
		private void SetScaling(int pixels, string text)
		{
			base.set_Width((double)pixels + this.scaleRectangle.get_Margin().get_Left() + this.scaleRectangle.get_Margin().get_Right());
			this.scaleString.Text = text;
			this.scaleRectangle.set_Width((double)pixels);
		}
		private void Refresh()
		{
			if (this.currentMetersPerPixel > 0.0)
			{
				this.SetScaling(this.currentMetersPerPixel);
			}
		}
		private void Scale_LayoutUpdated(object sender, EventArgs e)
		{
			if (this.previousMaxWidth != base.get_MaxWidth())
			{
				this.Refresh();
			}
		}
		protected virtual void OnPerPixelChanged()
		{
			this.SetScaling(this.MetersPerPixel);
		}
		private static void OnUnitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			((Scale)d).OnUnitChanged();
		}
		protected virtual void OnUnitChanged()
		{
			this.Refresh();
		}
		private static void OnCultureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			((Scale)d).OnCultureChanged();
		}
		protected virtual void OnCultureChanged()
		{
			if (this.Culture != null)
			{
				this.regionInfo = null;
			}
			else
			{
				this.regionInfo = ResourceUtility.GetRegionInfo(this.Culture.get_Name());
				OverlayResources.Culture = this.Culture;
			}
			this.Refresh();
		}
		private static int GetSingleDigitValue(double value)
		{
			int num = (int)Math.Floor(value);
			int[] array = Scale.singleDigitValues;
			for (int i = 0; i < array.Length; i++)
			{
				int num2 = array[i];
				if (num > num2)
				{
					return num2;
				}
			}
			return 1;
		}
		private static int GetMultiDigitValue(double value, double exponentOf10)
		{
			double[] array = Scale.multiDigitValues;
			for (int i = 0; i < array.Length; i++)
			{
				double num = array[i];
				if (value > num)
				{
					return (int)(num * exponentOf10);
				}
			}
			return (int)exponentOf10;
		}
		private static int LargestNiceNumber(double dIn)
		{
			double num = Math.Log(dIn) / Math.Log(10.0);
			double num2 = Math.Floor(num);
			double num3 = Math.Pow(10.0, num2);
			double value = dIn / num3;
			if (1.0 == num3)
			{
				return Scale.GetSingleDigitValue(value);
			}
			return Scale.GetMultiDigitValue(value, num3);
		}
		protected override AutomationPeer OnCreateAutomationPeer()
		{
			return new BaseAutomationPeer(this, "Scale");
		}
	}
}
